package ng.demo.ws;

import java.io.IOException;
import java.net.URI;
import java.util.concurrent.CountDownLatch;

import javax.websocket.ClientEndpoint;
import javax.websocket.CloseReason;
import javax.websocket.ContainerProvider;
import javax.websocket.DeploymentException;
import javax.websocket.EndpointConfig;
import javax.websocket.MessageHandler.Whole;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.WebSocketContainer;

@ClientEndpoint
public class WebsocketClientEndpoint {

	private final CountDownLatch latch;
	private Whole<String> messageHandler;
	private Session session = null;

	public WebsocketClientEndpoint(URI path) {
		this.latch = new CountDownLatch(1);
		WebSocketContainer container = ContainerProvider.getWebSocketContainer();
		try {
			container.connectToServer(this, path);
		} catch (DeploymentException | IOException e) {
			e.printStackTrace();
		}
	}

	@OnOpen
	public void onOpen(Session session, EndpointConfig config) {
		System.out.printf("opening websocket %s%n", session.getId());
		this.session = session;
		latch.countDown();
	}

	@OnClose
	public void onClose(Session session, CloseReason reason) {
		System.out.printf("closing websocket %s reason %s%n", session.getId(), reason);
		this.session = null;
	}

	@OnMessage
	public void onMessage(String message) {
		if (this.messageHandler != null) {
			messageHandler.onMessage(message);
		}
	}

	@OnError
	public void onError(Session session, Throwable thr) {
		thr.printStackTrace();
	}

	public void sendMessage(String message) {
		try {
			this.session.getBasicRemote().sendText(message);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public Session getSession() {
		return session;
	}

	public CountDownLatch getLatch() {
		return latch;
	}

	public Whole<String> getMessageHandler() {
		return messageHandler;
	}

	public WebsocketClientEndpoint setMessageHandler(Whole<String> messageHandler) {
		this.messageHandler = messageHandler;
		return this;
	}

}
